/*

Program : Jacobi iteration
*/

#include"matrix.h"




class JacobiIteretion : public Matrix
{
    public: 
    Matrix A,B,prevVal,currVal;
   
   //constructor  
   JacobiIteretion();
   
   //distructor
      ~JacobiIteretion();
      

 
   //collection of all the methods to solve the equation 
   //passing parameter as the filename for matix A and matrix B
   void jacobi(char [50],char [50]);
   
   //initial iteration of the X0 matrix   
   void initialIteretion();
   
   //calculate iteration 
   //pass curr val for which the iteration is calculated 
   // as parameter 
   void iteretion(const int);   

};

JacobiIteretion::JacobiIteretion()
{
   //initialize all zero
   prevVal.row=B.row;
   currVal.row=B.row;
   
   currVal.column=B.column;
   prevVal.column=B.column;
   

}

JacobiIteretion::~JacobiIteretion()
{
   //initialize all zero
}


void JacobiIteretion::jacobi(char fnameA[50],char fnameB[50])
   {
   
    Matrix tol;
   
       A.readMatrix(fnameA); 
       A.printMatrix();
       
       B.readMatrix(fnameB);
       B.printMatrix();
       
       if(!isDiagonallyDominant())
       {
       cout<<"Making Matrix Diagonally dominant"<<endl;
       
           for(int i=0;i<A.row;i++)
	    if(!isDiagonallyDominant(i)) 
	      makeDiagonallyDominant(i); 
       } 
         
       
       initialIteretion();
       
        while(1)
	{
	   
	  for(int i=0;i<row;i++)      
	      iteretion(i);
	   currVal.printMatrix();
	   
	   tol=mod(prevVal-currVal);
	   
	   if(tol.isTolerable(0.000000001)==1)
	     break;
           prevVal=currVal;		 
         }
           
       
   }


void JacobiIteretion::initialIteretion()
{
     
     for(int i=0;i<row;i++)   
        prevVal.matrix[i][0]=((double)B.matrix[i][0])/((double)A.matrix[i][i]);    
    
   
}      
   

void JacobiIteretion::iteretion(int row)   
{
  double add;
  add=0;   
     for(int j=0;j<column;j++)
     {
         if(j!=row)
	  add=add+(double)(A.matrix[row][j]*prevVal.matrix[j][0]);
     }     
  
     
  add=(double)B.matrix[row][0]-add;
        
  currVal.matrix[row][0]=add/((double)A.matrix[row][row]);

 
}



